class ChromLoc
	include Comparable

	attr_reader :chrom, :start, :end

	def self.valid_string?(s)
		s =~ /^chr.*:\d*-\d*$/
	end

	def initialize(*args)

		@chrom = -1
		case(args.size)
			when 1
				arg = args[0]
				raise(ArgumentError, "Single ChromLoc arg must be a string") unless(arg.is_a?(String))
				raise(ArgumentError, "Invalid location string: #{arg}") unless(ChromLoc.valid_string?(arg))

				chrom, loc = arg.split(":")
				@chrom = chrom[/[0-9].*/]
				@start, @end = loc.split("-").map {|v| v.to_i}

			when 2
				@start, @end = args

			when 3
				@chrom, @start, @end = args

			else
				raise "Invalid number of arguments intializing ChromLoc"

		end

		# debugger if(@end > 100)
		@range = @end - @start

	end

	# If the chrom_loc is on the positive strand - the end is greater than the start
	def is_forward?
		@range > 0
	end

	def exp_compare
		is_forward? ? 1 : -1
	end

	def range
		@range.abs
	end

	def true_range
		@range
	end

	# If this loc is contained in another
	def is_contained?(ex_loc)
		exp = exp_compare
		(((self <=> ex_loc) == 1) && ((self.end <=> ex_loc.end) == -exp))
	end


	# If this loc is mostly contained by ex_loc
	def is_maj_contained?(ex_loc)
		exp = exp_compare

		if( (self.start <=> ex_loc.start) == exp)
			return true if( (self.end <=> ex_loc.end) == -exp )
			return true if(exp * (self.end - ex_loc.end) < @range / 2)
		else
			if( (self.end <=> ex_loc.start) == exp  && (self.end <=> ex_loc.end) == -exp)
				return true if(exp * (self.end - ex_loc.start) > @range / 2)
			end
		end

		false
	end

	def is_after?(loc)
		[0, exp_compare].index(self.start <=> loc.end) 
	end

	def is_before?(loc)
		[0, -exp_compare].index(self.end <=> loc.start)
	end

	def partly_after?(loc)
		exp_compare == (self.end <=> loc.end)
	end

	def partly_before?(loc)
		exp_compare == (self.start <=> loc.start)
	end

	def <=>(comp_loc)
		return 0 if(self.is_forward? != comp_loc.is_forward?)

		(@chrom && comp_loc.chrom) ?
			chrom_comp = @chrom <=> comp_loc.chrom : chrom_comp = 0
		return chrom_comp unless(chrom_comp == 0)

		is_forward? ? mult = 1 : mult = -1
		mult * (@start <=> comp_loc.start)
	end


end
